home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 March / macformat-022.iso / Shareware City / Developers / src / out-of-phase-102-c / OutOfPhase 1.02 Source / OutOfPhase Folder / SampleSelector.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-23  |  12.5 KB  |  354 lines  |  [TEXT/KAHL]

  1. /* SampleSelector.c */
  2. /*****************************************************************************/
  3. /*                                                                           */
  4. /*    Out Of Phase:  Digital Music Synthesis on General Purpose Computers    */
  5. /*    Copyright (C) 1994  Thomas R. Lawrence                                 */
  6. /*                                                                           */
  7. /*    This program is free software; you can redistribute it and/or modify   */
  8. /*    it under the terms of the GNU General Public License as published by   */
  9. /*    the Free Software Foundation; either version 2 of the License, or      */
  10. /*    (at your option) any later version.                                    */
  11. /*                                                                           */
  12. /*    This program is distributed in the hope that it will be useful,        */
  13. /*    but WITHOUT ANY WARRANTY; without even the implied warranty of         */
  14. /*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          */
  15. /*    GNU General Public License for more details.                           */
  16. /*                                                                           */
  17. /*    You should have received a copy of the GNU General Public License      */
  18. /*    along with this program; if not, write to the Free Software            */
  19. /*    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.              */
  20. /*                                                                           */
  21. /*    Thomas R. Lawrence can be reached at tomlaw@world.std.com.             */
  22. /*                                                                           */
  23. /*****************************************************************************/
  24.  
  25. #include "MiscInfo.h"
  26. #include "Audit.h"
  27. #include "Debug.h"
  28. #include "Definitions.h"
  29.  
  30. #include "SampleSelector.h"
  31. #include "Memory.h"
  32. #include "SampleList.h"
  33. #include "WaveTableList.h"
  34. #include "AlgoSampList.h"
  35. #include "AlgoWaveTableList.h"
  36.  
  37.  
  38. /* in the list, elements are cascaded as follows: */
  39. /*  <lowestbound>  <boundary2>  <boundary3>  <highestbound> */
  40. /*          <sampname1>   <sampname2>  <sampname2> */
  41. struct SampleSelectorRec
  42.     {
  43.         /* number of RANGES (i.e. unique sample intervals) */
  44.         long                                NumRanges;
  45.  
  46.         /* this is a list of the boundaries of the ranges, so there is one extra element */
  47.         SampRangeHzType*        BoundaryList; /* NumRanges + 1 elements */
  48.  
  49.         /* this is an array of sample names, one sample for each interval */
  50.         char**                            SampleNameList; /* NumRanges elements */
  51.  
  52.         /* this is an array of sampled object references.  it is not immediately valid */
  53.         void**                            ReferencedObjectList; /* NumRanges elements */
  54.  
  55.         /* this is the type of object that is referenced */
  56.         SampleSourceTypes*    ReferencedObjectTypeList; /* NumRanges elements */
  57.     };
  58.  
  59.  
  60. /* create a new sample selector record */
  61. SampleSelectorRec*        NewSampleSelectorList(double LowestBound)
  62.     {
  63.         SampleSelectorRec*    SampList;
  64.  
  65.         SampList = (SampleSelectorRec*)AllocPtrCanFail(sizeof(SampleSelectorRec),
  66.             "SampleSelectorRec");
  67.         if (SampList == NIL)
  68.             {
  69.              FailurePoint1:
  70.                 return NIL;
  71.             }
  72.         SampList->BoundaryList = (SampRangeHzType*)AllocPtrCanFail(
  73.             1 * sizeof(SampRangeHzType),"SampRangeHzType");
  74.         if (SampList->BoundaryList == NIL)
  75.             {
  76.              FailurePoint2:
  77.                 ReleasePtr((char*)SampList);
  78.                 goto FailurePoint1;
  79.             }
  80.         SampList->BoundaryList[0] = LowestBound;
  81.         SampList->SampleNameList = (char**)AllocPtrCanFail(0,"SampleNameList");
  82.         if (SampList->SampleNameList == NIL)
  83.             {
  84.              FailurePoint3:
  85.                 ReleasePtr((char*)SampList->BoundaryList);
  86.                 goto FailurePoint2;
  87.             }
  88.         SampList->NumRanges = 0;
  89.         SampList->ReferencedObjectList = NIL;
  90.         SampList->ReferencedObjectTypeList = NIL;
  91.         return SampList;
  92.     }
  93.  
  94.  
  95. /* dispose of a sample selector list */
  96. void                                    DisposeSampleSelectorList(SampleSelectorRec* SampList)
  97.     {
  98.         long                                Scan;
  99.  
  100.         CheckPtrExistence(SampList);
  101.         for (Scan = 0; Scan < SampList->NumRanges; Scan += 1)
  102.             {
  103.                 ReleasePtr(SampList->SampleNameList[Scan]);
  104.             }
  105.         if (SampList->ReferencedObjectList != NIL)
  106.             {
  107.                 ReleasePtr((char*)SampList->ReferencedObjectList);
  108.             }
  109.         if (SampList->ReferencedObjectTypeList != NIL)
  110.             {
  111.                 ReleasePtr((char*)SampList->ReferencedObjectTypeList);
  112.             }
  113.         ReleasePtr((char*)SampList->SampleNameList);
  114.         ReleasePtr((char*)SampList->BoundaryList);
  115.         ReleasePtr((char*)SampList);
  116.     }
  117.  
  118.  
  119. /* add a new sample thing, with it's upper bound.  the object becomes the */
  120. /* owner of the name string */
  121. MyBoolean                            AppendSampleSelector(SampleSelectorRec* SampList,
  122.                                                 double UpperBound, char* Name)
  123.     {
  124.         SampRangeHzType*        NewBoundaryList;
  125.         char**                            NewNameList;
  126.  
  127.         CheckPtrExistence(SampList);
  128.         CheckPtrExistence(Name);
  129.         NewBoundaryList = (SampRangeHzType*)ResizePtr((char*)SampList->BoundaryList,
  130.             sizeof(SampRangeHzType) * (1 + 1 + SampList->NumRanges));
  131.         if (NewBoundaryList == NIL)
  132.             {
  133.                 return False;
  134.             }
  135.         NewNameList = (char**)ResizePtr((char*)SampList->SampleNameList,
  136.             sizeof(char*) * (1 + SampList->NumRanges));
  137.         /* if this fails, we don't do any cleanup because it doesn't matter if the */
  138.         /* size of the array is a bit long -- the size is really determined by NumRanges */
  139.         if (NewNameList == NIL)
  140.             {
  141.                 return False;
  142.             }
  143.         SampList->BoundaryList = NewBoundaryList;
  144.         SampList->SampleNameList = NewNameList;
  145.         SampList->BoundaryList[SampList->NumRanges + 1] = UpperBound;
  146.         SampList->SampleNameList[SampList->NumRanges] = Name;
  147.         SampList->NumRanges += 1;
  148.         return True;
  149.     }
  150.  
  151.  
  152. /* get the number of sample ranges specified in the list */
  153. long                                    GetSampleSelectorListLength(SampleSelectorRec* SampList)
  154.     {
  155.         CheckPtrExistence(SampList);
  156.         return SampList->NumRanges;
  157.     }
  158.  
  159.  
  160. /* return the low bound frequency of a particular list entry */
  161. SampRangeHzType                GetSampleListEntryLowFreqBound(SampleSelectorRec* SampList,
  162.                                                 long Index)
  163.     {
  164.         CheckPtrExistence(SampList);
  165.         ERROR((Index < 0) || (Index >= SampList->NumRanges),PRERR(ForceAbort,
  166.             "GetSampleListEntryLowFreqBound:  index is out of range"));
  167.         PRNGCHK(SampList->BoundaryList,&(SampList->BoundaryList[Index]),
  168.             sizeof(SampList->BoundaryList[Index]));
  169.         return SampList->BoundaryList[Index];
  170.     }
  171.  
  172.  
  173. /* return the high bound frequency of a particular list entry */
  174. SampRangeHzType                GetSampleListEntryHighFreqBound(SampleSelectorRec* SampList,
  175.                                                 long Index)
  176.     {
  177.         CheckPtrExistence(SampList);
  178.         ERROR((Index < 0) || (Index >= SampList->NumRanges),PRERR(ForceAbort,
  179.             "GetSampleListEntryHighFreqBound:  index is out of range"));
  180.         PRNGCHK(SampList->BoundaryList,&(SampList->BoundaryList[Index + 1]),
  181.             sizeof(SampList->BoundaryList[Index + 1]));
  182.         return SampList->BoundaryList[Index + 1];
  183.     }
  184.  
  185.  
  186. /* get the actual ptr to the sample name */
  187. char*                                    GetSampleListEntryName(SampleSelectorRec* SampList, long Index)
  188.     {
  189.         CheckPtrExistence(SampList);
  190.         ERROR((Index < 0) || (Index >= SampList->NumRanges),PRERR(ForceAbort,
  191.             "GetSampleListEntryName:  index is out of range"));
  192.         PRNGCHK(SampList->SampleNameList,&(SampList->SampleNameList[Index]),
  193.             sizeof(SampList->SampleNameList[Index]));
  194.         return SampList->SampleNameList[Index];
  195.     }
  196.  
  197.  
  198. /* resolve named references to samples.  returns False if it can't */
  199. MyBoolean                            ResolveSamplesInSampleList(SampleSelectorRec* SampList,
  200.                                                 struct SampleListRec* SampleList,
  201.                                                 struct AlgoSampListRec* AlgoSampList)
  202.     {
  203.         long                                Scan;
  204.  
  205.         CheckPtrExistence(SampList);
  206.         CheckPtrExistence(SampleList);
  207.         CheckPtrExistence(AlgoSampList);
  208.         ERROR(SampList->ReferencedObjectList != NIL,PRERR(ForceAbort,
  209.             "ResolveSamplesInSampleList:  ReferencedObjectList is not NIL"));
  210.         ERROR(SampList->ReferencedObjectTypeList != NIL,PRERR(ForceAbort,
  211.             "ResolveSamplesInSampleList:  ReferencedObjectTypeList is not NIL"));
  212.  
  213.         SampList->ReferencedObjectList = (void**)AllocPtrCanFail(SampList->NumRanges
  214.             * sizeof(void*),"SampleSelectorRec:  ReferencedObjectList");
  215.         if (SampList->ReferencedObjectList == NIL)
  216.             {
  217.              FailurePoint1:
  218.                 return False;
  219.             }
  220.         SampList->ReferencedObjectTypeList = (SampleSourceTypes*)AllocPtrCanFail(
  221.             SampList->NumRanges * sizeof(SampleSourceTypes),
  222.             "SampleSelectorRec:  ReferencedObjectTypeList");
  223.         if (SampList->ReferencedObjectTypeList == NIL)
  224.             {
  225.              FailurePoint2:
  226.                 ReleasePtr((char*)SampList->ReferencedObjectList);
  227.                 SampList->ReferencedObjectList = NIL;
  228.                 goto FailurePoint1;
  229.             }
  230.  
  231.         for (Scan = 0; Scan < SampList->NumRanges; Scan += 1)
  232.             {
  233.                 PRNGCHK(SampList->SampleNameList,&(SampList->SampleNameList[Scan]),
  234.                     sizeof(SampList->SampleNameList[Scan]));
  235.                 SampList->ReferencedObjectList[Scan] = SampleListLookupNamedSample(
  236.                     SampleList,SampList->SampleNameList[Scan]);
  237.                 if (SampList->ReferencedObjectList[Scan] != NIL)
  238.                     {
  239.                         SampList->ReferencedObjectTypeList[Scan] = eDataSample;
  240.                     }
  241.                  else
  242.                     {
  243.                         SampList->ReferencedObjectList[Scan] = AlgoSampListLookupNamedAlgoSamp(
  244.                             AlgoSampList,SampList->SampleNameList[Scan]);
  245.                         if (SampList->ReferencedObjectList[Scan] != NIL)
  246.                             {
  247.                                 SampList->ReferencedObjectTypeList[Scan] = eAlgoSample;
  248.                             }
  249.                          else
  250.                             {
  251.                                 return False;
  252.                             }
  253.                     }
  254.             }
  255.  
  256.         return True;
  257.     }
  258.  
  259.  
  260. /* resolve named references to wave tables.  returns False if it can't */
  261. MyBoolean                            ResolveWaveTablesInSampleList(SampleSelectorRec* SampList,
  262.                                                 struct WaveTableListRec* WaveTableList,
  263.                                                 struct AlgoWaveTableListRec* AlgoWaveTableList)
  264.     {
  265.         long                                Scan;
  266.  
  267.         CheckPtrExistence(SampList);
  268.         CheckPtrExistence(WaveTableList);
  269.         CheckPtrExistence(AlgoWaveTableList);
  270.         ERROR(SampList->ReferencedObjectList != NIL,PRERR(ForceAbort,
  271.             "ResolveWaveTablesInSampleList:  ReferencedObjectList is not NIL"));
  272.         ERROR(SampList->ReferencedObjectTypeList != NIL,PRERR(ForceAbort,
  273.             "ResolveWaveTablesInSampleList:  ReferencedObjectTypeList is not NIL"));
  274.  
  275.         SampList->ReferencedObjectList = (void**)AllocPtrCanFail(SampList->NumRanges
  276.             * sizeof(void*),"SampleSelectorRec:  ReferencedObjectList");
  277.         if (SampList->ReferencedObjectList == NIL)
  278.             {
  279.              FailurePoint1:
  280.                 return False;
  281.             }
  282.         SampList->ReferencedObjectTypeList = (SampleSourceTypes*)AllocPtrCanFail(
  283.             SampList->NumRanges * sizeof(SampleSourceTypes),
  284.             "SampleSelectorRec:  ReferencedObjectTypeList");
  285.         if (SampList->ReferencedObjectTypeList == NIL)
  286.             {
  287.              FailurePoint2:
  288.                 ReleasePtr((char*)SampList->ReferencedObjectList);
  289.                 SampList->ReferencedObjectList = NIL;
  290.                 goto FailurePoint1;
  291.             }
  292.  
  293.         for (Scan = 0; Scan < SampList->NumRanges; Scan += 1)
  294.             {
  295.                 PRNGCHK(SampList->SampleNameList,&(SampList->SampleNameList[Scan]),
  296.                     sizeof(SampList->SampleNameList[Scan]));
  297.                 SampList->ReferencedObjectList[Scan] = WaveTableListLookupNamedWaveTable(
  298.                     WaveTableList,SampList->SampleNameList[Scan]);
  299.                 if (SampList->ReferencedObjectList[Scan] != NIL)
  300.                     {
  301.                         SampList->ReferencedObjectTypeList[Scan] = eDataWaveTable;
  302.                     }
  303.                  else
  304.                     {
  305.                         SampList->ReferencedObjectList[Scan]
  306.                             = AlgoWaveTableListLookupNamedAlgoWaveTable(AlgoWaveTableList,
  307.                             SampList->SampleNameList[Scan]);
  308.                         if (SampList->ReferencedObjectList[Scan] != NIL)
  309.                             {
  310.                                 SampList->ReferencedObjectTypeList[Scan] = eAlgoWaveTable;
  311.                             }
  312.                          else
  313.                             {
  314.                                 return False;
  315.                             }
  316.                     }
  317.             }
  318.  
  319.         return True;
  320.     }
  321.  
  322.  
  323. /* get the wave type of an entry */
  324. SampleSourceTypes            GetSampleListWaveType(SampleSelectorRec* SampList,
  325.                                                 long Index)
  326.     {
  327.         CheckPtrExistence(SampList);
  328.         ERROR(SampList->ReferencedObjectTypeList == NIL,PRERR(ForceAbort,
  329.             "GetSampleListWaveType:  type list is NIL (refs haven't been resolved yet)"));
  330.         CheckPtrExistence(SampList->ReferencedObjectTypeList);
  331.         ERROR((Index < 0) || (Index >= SampList->NumRanges),PRERR(ForceAbort,
  332.             "GetSampleListWaveType:  index out of range"));
  333.         PRNGCHK(SampList->ReferencedObjectTypeList,
  334.             &(SampList->ReferencedObjectTypeList[Index]),
  335.             sizeof(SampList->ReferencedObjectTypeList[Index]));
  336.         return SampList->ReferencedObjectTypeList[Index];
  337.     }
  338.  
  339.  
  340. /* get a reference to the object */
  341. void*                                    GetSampleListWaveReference(SampleSelectorRec* SampList,
  342.                                                 long Index)
  343.     {
  344.         CheckPtrExistence(SampList);
  345.         ERROR(SampList->ReferencedObjectList == NIL,PRERR(ForceAbort,
  346.             "GetSampleListWaveReference:  type list is NIL (refs haven't been resolved yet)"));
  347.         CheckPtrExistence(SampList->ReferencedObjectList);
  348.         ERROR((Index < 0) || (Index >= SampList->NumRanges),PRERR(ForceAbort,
  349.             "GetSampleListWaveReference:  index out of range"));
  350.         PRNGCHK(SampList->ReferencedObjectList,&(SampList->ReferencedObjectList[Index]),
  351.             sizeof(SampList->ReferencedObjectList[Index]));
  352.         return SampList->ReferencedObjectList[Index];
  353.     }
  354.